/*
 * $Id: FunctionList.java,v 1.2 2003/05/21 23:06:09 znamenacek Exp $
 *
 * Copyright (c) Tomas Znamenacek
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

package net.sf.vofce.gui;

import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ResourceBundle;

import net.sf.vofce.guts.Function;
import net.sf.vofce.project.Config;
import net.sf.vofce.project.Project;

/**
 * A GUI component showing list of functions.
 *
 * @author Tomas Znamenacek
 */
public class FunctionList extends JSpacedPanel
	implements MouseListener, ListSelectionListener {

	/** The table with functions. */
	protected JTable functions;

	/** Instance of the <code>Config</code>. */
	protected Config config = Config.getInstance();

	/** Instance of the <code>Project</code>. */
	protected Project project = Project.getInstance();

	/** Localised resource strings. */
	protected static ResourceBundle resources;

	/** The color picker dialog. */
	protected ColorPicker colorPicker;

	protected InputDialog inputDialog;
	
	/** Creates the component. */
	public FunctionList() {

		super();

		colorPicker = new ColorPicker(null);
		inputDialog = new InputDialog(null);
		
		setLayout(new BorderLayout());
		
		Model tableModel = new Model();
		project.addListDataListener(tableModel);
		
		functions = new JTable(tableModel);
		functions.setDefaultRenderer(Color.class, new ColorRenderer(true));
		functions.addMouseListener(this);
		functions.getSelectionModel().addListSelectionListener(this);
	
		functions.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
		functions.getColumnModel().getColumn(1).setMaxWidth(60);

		JScrollPane scroller = new JScrollPane(functions);
		add(scroller, BorderLayout.CENTER);
		
		JButton addButton = new JButton(newFunction);
		JButton removeButton = new JButton(removeFunction);
		removeFunction.setEnabled(false);

		JPanel buttonPanel = new JSpacedPanel();
		Box buttonBar = Box.createHorizontalBox();
		buttonBar.add(Box.createHorizontalGlue());
		buttonBar.add(addButton);
		buttonBar.add(Box.createHorizontalStrut(10));
		buttonBar.add(removeButton);
		buttonPanel.add(buttonBar);

		add(buttonPanel, BorderLayout.SOUTH);
	}

	//
	// Method implementing ListSelectionListener
	// 

	public void valueChanged(ListSelectionEvent le) {

		removeFunction.setEnabled(! ((ListSelectionModel) le.getSource()).isSelectionEmpty());
	}

	//
	// Methods implementing MouseListener
	// 
	
	public void mousePressed(MouseEvent e) {}
	public void mouseReleased(MouseEvent e) {}
	public void mouseEntered(MouseEvent e) {}
	public void mouseExited(MouseEvent e) {}

	/**
	 * Respond to double mouse click in the list area.
	 */
	public void mouseClicked(MouseEvent e) {

		if (e.getClickCount() != 2) {
			return;
		}
		
		int row = functions.getSelectedRow();
		int column = functions.getSelectedColumn();
		
		if (row == -1) {

			// add function
			Function f = inputDialog.show(null);
			if (f != null) { project.addFunction(f); }

		} else if (column == 0) {

			// change function
			Function f = inputDialog.show(project.getFunction(row));
			project.changeFunction(row, f);

		} else {

			// change function color
			colorPicker.setColor(config.getFunctionColor(row));
			colorPicker.show();

			if (! colorPicker.cancelled()) {
				config.setFunctionColor(row, colorPicker.getColor());
			}
		}
	}

	//
	// Actions
	// 

	/**
	 * Returns image associated with given resource id.
	 */
	private ImageIcon getIcon(String id) {

		return new ImageIcon(getClass().getResource("/" + id));
	}

	/** Add new function. */
	private AbstractAction newFunction = new AbstractAction(
		resources.getString("misc.add"),
		getIcon("add.gif")
	) {
		public void actionPerformed(ActionEvent e) {
			
			Function f = inputDialog.show(null);
			if (f != null) { project.addFunction(f); }
		}
	};
	
	/** Remove function. */
	private AbstractAction removeFunction= new AbstractAction(
		resources.getString("misc.remove"),
		getIcon("delete.gif")
	) {
		public void actionPerformed(ActionEvent e) {
		
			int[] indices = functions.getSelectedRows();

			for (int i=0; i < indices.length; i++) {
				project.removeFunction(indices[i]-i);
			}
		}
	};
	
	//
	// The table model
	//
	
	/** A table model representing the list of functions. */
	class Model extends AbstractTableModel implements ListDataListener {

		String[] columnNames = new String[2];

		public Model() {

			columnNames[0] = resources.getString("misc.function");
			columnNames[1] = resources.getString("misc.color");
		}
		
		public Class getColumnClass(int columnIndex) {

			return getValueAt(0, columnIndex).getClass();
		}

		public int getColumnCount() {

			return columnNames.length;
		}
		
		public String getColumnName(int columnIndex) {

			return columnNames[columnIndex];
		}

		public int getRowCount() {

			return project.getSize();
		}

		public Object getValueAt(int row, int column) {

			if (column == 0) {
				return project.getElementAt(row);
			} else {
				return config.getFunctionColor(row);
			}
		}

		public boolean isCellEditable(int row, int column) {

			return false;
		}

		public void setValueAt(Object value, int row, int column) {

			//...
		}

		//
		// Methods implementing ListDataListener
		// 
		
		public void contentsChanged(ListDataEvent le) {
			fireTableRowsUpdated(le.getIndex0(), le.getIndex1());
		}

		public void intervalAdded(ListDataEvent le) {
			fireTableRowsInserted(le.getIndex0(), le.getIndex1());
		}

		public void intervalRemoved(ListDataEvent le) {
			fireTableRowsDeleted(le.getIndex0(), le.getIndex1());
		}
	}

	static {
		
		resources = ResourceBundle.getBundle("net.sf.vofce.gui.resources");
	}
}
